
#ifndef __APR_MUTEX_H
#define __APR_MUTEX_H

#include <apr-1/apr_thread_mutex.h>
#include <apr-1/apr_thread_cond.h>

/** A wrapper around the APR mutex. */
class APRMutex
{
   private:
      /** Initialise the APR mutex object (and condition variable).
       * 
       * @param mp
       * The memory pool to use to allocate space for this mutex. */
      bool init(apr_pool_t *mp)
      {
         apr_thread_mutex_create(&aprt_mutex, APR_THREAD_MUTEX_UNNESTED, mp);
         apr_thread_cond_create(&aprt_cond, mp);
         return true;
      }
      /** Destroy the APR mutex object (and condition variable). */
      bool destroy()
      {
         apr_thread_mutex_destroy(aprt_mutex);
         apr_thread_cond_destroy(aprt_cond);
         return true;
      }
   protected:
      /** The mutex being wrapped. */
      apr_thread_mutex_t *aprt_mutex;
      /** The condition variable being wrapped. */
      apr_thread_cond_t *aprt_cond;
   public:
      /** Initialise the wrapper and the wrapped items using the given memory pool. */
      APRMutex(apr_pool_t *mp) { init(mp); }
      /** Destructor for the wrapper and the wrapped items. */
      virtual ~APRMutex() { destroy(); }
      /** Lock the resource. */
      bool lock() { apr_thread_mutex_lock(aprt_mutex); return true; }
      /** Unlock the resource. */
      bool unlock() { apr_thread_mutex_unlock(aprt_mutex); return true; }
      /** Wait on the signal. */
      bool wait() { apr_thread_cond_wait(aprt_cond, aprt_mutex); return true; }
      /** Wait for a time on the signal. */
      bool timedWait(int msecs) { apr_thread_cond_timedwait(aprt_cond, aprt_mutex, (apr_interval_time_t)msecs); return true; }
      /** Broadcast signal to stop waits waiting. */
      bool signal() { apr_thread_cond_signal(aprt_cond); return true; }
};

#endif
